﻿Imports WiremetModel.Entities.SupplyOrders
Imports WiremetModel.Entities
Imports WiremetModel.Exceptions
Imports GMap.NET
Imports GMap.NET.WindowsForms
Imports CrystalDecisions.CrystalReports.Engine


Public Class DieOrderView

    Private _unitOfWork As UnitOfWork
    Private _dieOrderDictionary As IDictionary(Of Integer, DieOrder)
    Private _supplierLocationOverlay As GMapOverlay
    Private _detailsPanelWidth As Integer


    Private Structure Filter
        Public orderNumber As String
        Public submitDate As Date?
        Public orderLineDiameter As String
    End Structure


    Public Sub New()
        InitializeComponent()
        _unitOfWork = New UnitOfWork()
        RefreshView()
    End Sub

    Private Sub DieOrderView_FormClosed(ByVal sender As Object, ByVal e As FormClosedEventArgs) Handles Me.FormClosed
        _unitOfWork.Dispose()
    End Sub

    Private Sub RefreshView()
        RefreshViewData()
        RefreshDieOrderTable(_dieOrderDictionary.Values)
    End Sub

    Private Sub RefreshViewData()

        Dim dieOrderRepository As New Repository(Of DieOrder)(_unitOfWork)
        _dieOrderDictionary = dieOrderRepository.GetAll().ToDictionary(Function(x) x.Id, Function(x) x)

    End Sub

    Private Sub RefreshDieOrderTable(ByVal dieOrderList As IEnumerable(Of DieOrder))

        dgv_DieOrder.Rows.Clear()
        For Each dieOrder As DieOrder In dieOrderList.OrderByDescending(Function(x) x.OrderNumber)
            dgv_DieOrder.Rows.Add(
                dieOrder.Id,
                dieOrder.OrderNumber,
                dieOrder.Supplier.CompanyName,
                dieOrder.SubmitDate.ToShortDateString(),
                If(dieOrder.ExpectedDeliveryDate.HasValue, dieOrder.ExpectedDeliveryDate.Value.ToShortDateString(), String.Empty),
                dieOrder.OrderLines.Sum(Function(x) x.Quantity).ToString()
            )
        Next
    End Sub


    Private Function GetSelectedDieOrder() As DieOrder
        Return _dieOrderDictionary(CInt(dgv_DieOrder.SelectedRows(0).Cells("DieOrderId").Value))

    End Function

    Private Sub RefreshDetailsPanel()
        Dim dieOrder As DieOrder = GetSelectedDieOrder()

        tb_Employee.Text = dieOrder.Employee.ToString()
        tb_Note.Text = dieOrder.Note
        Dim supplierAddres As SupplierAddress = dieOrder.Supplier.SupplierAddresses.FirstOrDefault(Function(x) x.Address.Id = dieOrder.SubmitAddress.Id)
        tb_SubmitAddress.Text = If(IsNothing(supplierAddres), "Usunięty", supplierAddres.Description) & vbNewLine &
            dieOrder.SubmitAddress.ToString()

        tb_TelephoneNumber.Text = dieOrder.Supplier.TelephoneNumber
        tb_FaxNumber.Text = dieOrder.Supplier.FaxNumber
        tb_EmailAddress.Text = dieOrder.Supplier.EmailAddress

        dgv_DieOrderLine.Rows.Clear()
        For Each dieOrderLine As DieOrderLine In dieOrder.OrderLines

            dgv_DieOrderLine.Rows.Add(
                dieOrderLine.Id,
                dieOrderLine.Diameter,
                dieOrderLine.DiameterToleranceMinus & "; " & dieOrderLine.DiameterTolerancePlus,
                dieOrderLine.CasingDiameter & " x " & dieOrderLine.CasingHeight,
                dieOrderLine.Quantity
            )
        Next
    End Sub

    Private Sub dgv_DieOrder_SelectionChanged(ByVal sender As Object, ByVal e As EventArgs) Handles dgv_DieOrder.SelectionChanged
        If Not sc_DieOrderData.Panel2Collapsed AndAlso Not dgv_DieOrder.SelectedRows.Count = 0 Then
            RefreshDetailsPanel()
        End If
    End Sub



#Region "Filter"

    Private Function CreateFilter() As Filter
        Return New Filter With
        {
            .orderNumber = tb_Filter_OrderNumber.Text.Trim(),
            .submitDate = If(dtp_Filter_SumbitDate.Checked, dtp_Filter_SumbitDate.Value, CType(Nothing, Date?)),
            .orderLineDiameter = tb_Filter_OrderLineDiameter.Text.Trim()
        }
    End Function


    Private Function IsDieOrderSatisfiedByFilter(ByVal dieOrder As DieOrder, ByVal filter As Filter) As Boolean
        Return dieOrder.OrderNumber.StartsWith(filter.orderNumber, StringComparison.CurrentCultureIgnoreCase) AndAlso
            (Not filter.submitDate.HasValue OrElse dieOrder.SubmitDate.ToShortDateString() = filter.submitDate.Value.ToShortDateString()) AndAlso
            (dieOrder.OrderLines.Any(Function(x) x.Diameter.ToString().StartsWith(filter.orderLineDiameter)))
    End Function


    Private Sub RunFilter(ByVal filter As Filter)
        Dim filteredDieOrderList As New List(Of DieOrder)

        For Each dieOrder As DieOrder In _dieOrderDictionary.Values
            If IsDieOrderSatisfiedByFilter(dieOrder, filter) Then
                filteredDieOrderList.Add(dieOrder)
            End If
        Next

        RefreshDieOrderTable(filteredDieOrderList)
    End Sub



    Private Sub ClearFilter()

        tb_Filter_OrderNumber.Text = String.Empty
        dtp_Filter_SumbitDate.Value = Date.Now
        dtp_Filter_SumbitDate.Checked = False
        tb_Filter_OrderLineDiameter.Text = String.Empty

    End Sub

    Private Sub btn_RunFilter_Click(sender As System.Object, e As System.EventArgs)
        RunFilter(CreateFilter())
    End Sub

    Private Sub btn_ClearFilter_Click(sender As System.Object, e As System.EventArgs)
        ClearFilter()
        RunFilter(CreateFilter())
    End Sub

    Private Sub filterInput_KeyDown(sender As Object, e As KeyEventArgs) Handles tb_Filter_OrderLineDiameter.KeyDown, tb_Filter_OrderNumber.KeyDown, dtp_Filter_SumbitDate.KeyDown
        If e.KeyCode = Keys.Enter Then
            RunFilter(CreateFilter())
        End If
    End Sub
#End Region

    Private Sub EnsureDieOrderIsSelected()
        If dgv_DieOrder.SelectedRows.Count = 0 Then
            Throw New Exception("Proszę, wybierz zamówienie, aby kontynuować.")
        End If
    End Sub
    Private Sub PresentDieOrderReport(ByVal dieOrder As DieOrder)
        Dim dieOrderReport As ReportDocument = New DieOrderReportService().GenerateReport(dieOrder)
        Dim reportPreviewForm As New frmPrintViewer(dieOrderReport, False)
        reportPreviewForm.WindowState = FormWindowState.Maximized
        reportPreviewForm.Show()
    End Sub

    Private Sub ts_btn_AddDieOrder_Click(sender As System.Object, e As System.EventArgs) Handles ts_btn_AddDieOrder.Click
        Try
            Dim dieOrderInputDialog As New DieOrderInputDialog(_unitOfWork)
            If dieOrderInputDialog.ShowDialog = Windows.Forms.DialogResult.OK Then
                Cursor = Cursors.WaitCursor

                Dim dieOrder As DieOrder = dieOrderInputDialog.DieOrder
                Dim dieOrderRepository As New Repository(Of DieOrder)(_unitOfWork)

                _unitOfWork.BeginTransaction()
                dieOrderRepository.Add(dieOrder)
                _unitOfWork.CommitTransaction()

                PresentDieOrderReport(dieOrder)

                _dieOrderDictionary.Add(dieOrder.Id, dieOrder)
                RefreshDieOrderTable(_dieOrderDictionary.Values)
                ClearFilter()
                RunFilter(CreateFilter())

            End If
        Catch ex As Exception
            MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
        Finally
            Cursor = Cursors.Default
        End Try
    End Sub

    Private Sub ts_btn_EditDieOrder_Click(sender As System.Object, e As System.EventArgs) Handles ts_btn_EditDieOrder.Click
        Try
            EnsureDieOrderIsSelected()
            Dim selectedDieOrder As DieOrder = GetSelectedDieOrder()
            Dim dieOrderInputDialog As New DieOrderInputDialog(_unitOfWork, selectedDieOrder)

            If dieOrderInputDialog.ShowDialog() = Windows.Forms.DialogResult.OK Then
                Cursor = Cursors.WaitCursor

                Dim dieOrder As DieOrder = dieOrderInputDialog.DieOrder
                Dim dieOrderRepository As New Repository(Of DieOrder)(_unitOfWork)

                _unitOfWork.BeginTransaction()
                dieOrderRepository.Update(dieOrder)
                _unitOfWork.CommitTransaction()

                PresentDieOrderReport(dieOrder)

                _dieOrderDictionary(dieOrder.Id) = dieOrder
                RefreshDieOrderTable(_dieOrderDictionary.Values)
                ClearFilter()
                RunFilter(CreateFilter())

            End If
        Catch ex As Exception
            MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
        Finally
            Cursor = Cursors.Default
        End Try
    End Sub

    Private Sub ts_btn_DeleteDieOrder_Click(sender As System.Object, e As System.EventArgs) Handles ts_btn_DeleteDieOrder.Click
        Try
            EnsureDieOrderIsSelected()
            Dim selectedDieOrder As DieOrder = GetSelectedDieOrder()
            Dim confirmationDialogResult As DialogResult = MessageBox.Show("Czy jesteś pewien?", "Uwaga", MessageBoxButtons.YesNo, MessageBoxIcon.Warning)

            If confirmationDialogResult = DialogResult.Yes Then
                Cursor = Cursors.WaitCursor

                Dim dieOrderRepository As New Repository(Of DieOrder)(_unitOfWork)

                _unitOfWork.BeginTransaction()
                dieOrderRepository.Delete(selectedDieOrder)
                _unitOfWork.CommitTransaction()

                _dieOrderDictionary.Remove(selectedDieOrder.Id)
                RefreshDieOrderTable(_dieOrderDictionary.Values)

                MessageBox.Show("Zamówienie zostało usunięte.", "Potwierdzenie", MessageBoxButtons.OK, MessageBoxIcon.Information)
            End If
        Catch ex As Exception
            MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
        Finally
            Cursor = Cursors.Default
        End Try
    End Sub

    Private Sub ts_btn_RefreshView_Click(sender As System.Object, e As System.EventArgs) Handles ts_btn_RefreshView.Click
        Try
            Cursor = Cursors.WaitCursor
            _unitOfWork.Dispose()
            _unitOfWork = New UnitOfWork()
            RefreshViewData()
            ClearFilter()
            RunFilter(CreateFilter())

        Catch ex As Exception
            MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
        Finally
            Cursor = Cursors.Default
        End Try
    End Sub

    Private Sub ts_btn_CopyOrder_Click(sender As System.Object, e As System.EventArgs) Handles ts_btn_CopyOrder.Click
        Try
            EnsureDieOrderIsSelected()
            Dim selectedDieOrder As DieOrder = GetSelectedDieOrder()
            Dim copiedOrder As New DieOrder With {
                .Currency = selectedDieOrder.Currency,
                .Employee = selectedDieOrder.Employee,
                .Note = selectedDieOrder.Note,
                .OrderLines = selectedDieOrder.OrderLines.Select(Function(x) New DieOrderLine With {
                                                                     .CasingDiameter = x.CasingDiameter,
                                                                     .CasingHeight = x.CasingHeight,
                                                                     .Diameter = x.Diameter,
                                                                     .DiameterToleranceMinus = x.DiameterToleranceMinus,
                                                                     .DiameterTolerancePlus = x.DiameterTolerancePlus,
                                                                     .Quantity = x.Quantity
                                                                 }).ToList(),
                .SubmitAddress = selectedDieOrder.SubmitAddress,
                .SubmitDate = Date.Now.Date,
            .Supplier = selectedDieOrder.Supplier
            }
            '.ExpectedDeliveryDate = selectedDieOrder.ExpectedDeliveryDate,
            For Each orderLine As DieOrderLine In copiedOrder.OrderLines
                orderLine.DieOrder = copiedOrder
            Next

            Dim dieOrderInputDialog As New DieOrderInputDialog(_unitOfWork, copiedOrder)
            If dieOrderInputDialog.ShowDialog = Windows.Forms.DialogResult.OK Then
                Cursor = Cursors.WaitCursor

                Dim dieOrder As DieOrder = dieOrderInputDialog.DieOrder
                Dim dieOrderRepository As New Repository(Of DieOrder)(_unitOfWork)

                _unitOfWork.BeginTransaction()
                dieOrderRepository.Add(dieOrder)
                _unitOfWork.CommitTransaction()

                PresentDieOrderReport(dieOrder)

                _dieOrderDictionary.Add(dieOrder.Id, dieOrder)
                RefreshDieOrderTable(_dieOrderDictionary.Values)
                ClearFilter()
                RunFilter(CreateFilter())

            End If
        Catch ex As Exception
            MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
        Finally
            Cursor = Cursors.Default
        End Try
    End Sub

    Private Sub ts_btn_PrintDieOrder_Click(sender As System.Object, e As System.EventArgs) Handles ts_btn_PrintDieOrder.Click
        Try
            EnsureDieOrderIsSelected()
            Cursor = Cursors.WaitCursor
            Dim selectedDieOrder As DieOrder = GetSelectedDieOrder()
            PresentDieOrderReport(selectedDieOrder)
        Catch ex As Exception
            MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
        Finally
            Cursor = Cursors.Default
        End Try
    End Sub

    Private Sub ChangeDetailsPanelVisibility()
        If sc_DieOrderData.Panel2Collapsed Then
            sc_DieOrderData.Panel2Collapsed = False
            Me.Width += _detailsPanelWidth + sc_DieOrderData.SplitterWidth
        Else
            _detailsPanelWidth = sc_DieOrderData.Panel2.Width
            Me.Width -= _detailsPanelWidth + sc_DieOrderData.SplitterWidth
            sc_DieOrderData.Panel2Collapsed = True
        End If
        Refresh()
    End Sub

    Private Sub ts_btn_Details_Click(sender As System.Object, e As System.EventArgs) Handles ts_btn_Details.Click
        ChangeDetailsPanelVisibility()
        RefreshDetailsPanel()
    End Sub

End Class